package com.tma.demo;

import java.lang.Thread.State;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class WorkerThreadActivity extends Activity implements OnClickListener {
    private static final String TAG = "WorkerThreadActivity";
    private static final String MSG_KEY = "status";
    private TextView mTaskProgressTextView;
    private Button mWorkerThreadButton;
    private Thread mWorkerThread;
    private StatusHandler mHandler;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_worker_thread);

        mTaskProgressTextView = (TextView) findViewById(R.id.tv_task_progress);
        mWorkerThreadButton = (Button) findViewById(R.id.btn_do_long_task);
        mWorkerThreadButton.setOnClickListener(this);
    }

    public void onClick(View v) {
        handleButtonClicked();
    }

    private void handleButtonClicked() {
        if (mHandler == null) {
            mHandler = new StatusHandler(this);
            mWorkerThread = new Thread(new WorkerRunnable(mHandler));
            mWorkerThread.start();
            return;
        }

        if (mWorkerThread.getState() != State.TERMINATED) {
            Toast.makeText(this, "The worker thread is new or alive",
                    Toast.LENGTH_SHORT).show();
        } else {
            Log.i(TAG, "The worker thread is dead, start it again");
            mWorkerThread = new Thread(new WorkerRunnable(mHandler));
            mWorkerThread.start();
        }
    }

    public void printWorkerStatus(String status) {
        mTaskProgressTextView.setText(status);
    }

    /**
     * Update worker thread's status to UI
     */
    private static class StatusHandler extends Handler {
        private WorkerThreadActivity mActivity;

        public StatusHandler(WorkerThreadActivity activity) {
            mActivity = activity;
        }

        @Override
        public void handleMessage(Message msg) {
            
            Bundle bundle = msg.getData();
            String status = bundle.getString("status");
            Log.i(TAG, status);
            mActivity.printWorkerStatus(status);
        }
    }

    /**
     * Do heavy task<br/>
     * Report task status to the main thread
     */
    private class WorkerRunnable implements Runnable {
        private Handler myHandler = null;

        public WorkerRunnable(Handler handler) {
            myHandler = handler;
        }

        public void run() {
            // 1. DO REAL HEAVY JOB HERE
            // 2. REPORT STATUS BACK TO MAIN THREAD
            informStart();
            sleep(1000);

            for (int i = 1; i <= 1000; i++) {
                Log.i(TAG, "processing  " + i);
                informMiddle(i, 100);
                sleep(50); // simulate heavy work
            }
            informFinish();
        }

        private void sleep(long time) {
            try {
                Thread.sleep(time);
            } catch (InterruptedException e) {
            }
        }

        private void informStart() {
            Message msg = Message.obtain();
            msg.setData(makeBundle("Starting..."));
            myHandler.sendMessage(msg);
        }

        private void informMiddle(int percent, int total) {
            Message msg = Message.obtain();
            msg.setData(makeBundle("Working " + percent + "/" + total));
            myHandler.sendMessage(msg);
        }

        private void informFinish() {
            Message msg = Message.obtain();
            msg.setData(makeBundle("Done"));
            myHandler.sendMessage(msg);
        }

        private Bundle makeBundle(String status) {
            Bundle bundle = new Bundle();
            bundle.putString(MSG_KEY, status);
            return bundle;
        }
    }
}
